package cn.sdjzu.exercise;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.security.InvalidParameterException;
import java.util.List;
import com.dwin.navy.serialportapi.SerialPortOpt;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.ActivityManager.RunningTaskInfo;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.DialogInterface.OnClickListener;
import android.os.Bundle;
import android.widget.Toast;

public abstract class TransmissionActivity extends BasedActivity {
	protected ExerciseApp mApplication;
	private SerialPortOpt serialPort;
	protected Socket socket;
	protected OutputStream mOutputStream;
	private InputStream mInputStream;
	private ReadThread mReadThread;
	MyTimeThread timer;
	public float scale;
	protected ConnThread conn;
	public String IP = "";
	public int port;
	public String TransmissionWay;

	private class ReadThread extends Thread {
		@Override
		public void run() {
			super.run();
			// 定义一个包的最大长度
			int maxLength = 2048;
			byte[] buffer = new byte[maxLength];
			// 每次收到实际长度
			int available = 0;
			// 当前已经收到包的总长度
			int currentLength = 0;
			timer = new MyTimeThread();
			timer.start();
			while (!isInterrupted()) {
				try {
					available = mInputStream.available();
					if (available > 0) {
						// 防止超出数组最大长度导致溢出
						if (available > maxLength - currentLength) {
							available = 0;
							currentLength = 0;
						}
						mInputStream.read(buffer, currentLength, available);
						currentLength += available;
						timer.count = 0;
					}
					if (buffer[0] != 1) {
						currentLength = 0;
					}
					if ((buffer[0] == 1) && (currentLength >= 5)
							&& (timer.count > 10)) {
						onDataReceived(buffer, currentLength, currentLength);
						available = 0;
						currentLength = 0;
					}
				} catch (IOException e) {
					e.printStackTrace();
					return;
				}
			}
		}
	}

	class MyTimeThread extends Thread {
		public int count;

		public MyTimeThread() {
			count = 0;
		}

		@Override
		public void run() {
			do {
				try {
					sleep(1);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				if (count < 1000)
					count++;
			} while (!isInterrupted());
		}
	}

	private void DisplayError(String errMsg) {
		AlertDialog.Builder b = new AlertDialog.Builder(this);
		b.setTitle("Error");
		b.setMessage(errMsg);
		b.setPositiveButton("OK", new OnClickListener() {
			public void onClick(DialogInterface dialog, int which) {
				TransmissionActivity.this.finish();
			}
		});
		b.show();
	}

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		mApplication = (ExerciseApp) getApplication();
		preferences = getSharedPreferences("itYao", Context.MODE_WORLD_READABLE);
		editor = preferences.edit();
		IP = preferences.getString("IP", "");
		port = preferences.getInt("port", 0);
		TransmissionWay = preferences
				.getString("TransmissionWay", "selectWIFI");
		TransToast = Toast.makeText(this, "通讯未连接，请重新连接", Toast.LENGTH_LONG);
	}

	private void openSerialPort() {
		serialPort.openDev(serialPort.mDevNum);
		serialPort.setSpeed(serialPort.mFd, serialPort.mSpeed);
		serialPort.setParity(serialPort.mFd, serialPort.mDataBits,
				serialPort.mStopBits, serialPort.mParity);
		mInputStream = serialPort.getInputStream();
		mOutputStream = serialPort.getOutputStream();
	}

	protected void closeSerialPort() {
		try {
			mInputStream.close();
			mOutputStream.close();
			serialPort.closeDev(serialPort.mFd);
			serialPort = null;
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	@Override
	public void onResume() {
		initConn();
		super.onResume();
	}

	public void close() {
		Intent intent = new Intent();
		intent.setAction("ExitApp");
		this.sendBroadcast(intent);
		super.finish();
	}

	@Override
	protected void onPause() {
		shutdownConn();
		super.onPause();
	}

	
	public void changeTXT(byte[] command) {
		TXT.OpenTxtFile();
		TXT.readTxtFile();
		long time = System.currentTimeMillis();
		String com = time + "---->" + bytesToHexString(command);
		try {
			TXT.writeTxtFile(com);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}


	public void changeTXT1(byte[] buffer) {
		TXT.OpenTxtFile();
		TXT.readTxtFile();
		long time = System.currentTimeMillis();
		int i = buffer.length;
		String com = time + "<--" + i + "--" + bytesToHexString(buffer);
		try {
			TXT.writeTxtFile(com);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/*
	 * 将16进制byte[]转化为相应字符串
	 */
	public static String bytesToHexString(byte[] src) {
		StringBuilder stringBuilder = new StringBuilder();
		if (src == null || src.length <= 0) {
			return null;
		}
		for (int i = 0; i < src.length; i++) {
			int v = src[i] & 0xFF;
			String hv = Integer.toHexString(v);
			if (hv.length() < 2) {
				stringBuilder.append(0);
			}
			stringBuilder.append(hv);
		}
		return stringBuilder.toString();
	}

	class ConnThread extends Thread {
		@Override
		public void run() {
			if (TransmissionWay.equals("selectWIFI")) {
				try {
					socket = new Socket();
					SocketAddress remoteAddr = new InetSocketAddress(IP, port);
					socket.connect(remoteAddr);
					mOutputStream = socket.getOutputStream();
					mInputStream = socket.getInputStream();
				} catch (Exception e) {
					e.printStackTrace();
					TransToast.show();
					Intent intent = new Intent(TransmissionActivity.this,
							ControlPanelActivity.class);
					startActivity(intent);
					TransmissionActivity.this.finish();
					onDestroy();
				}
			} else {
				// 获取串口
				serialPort = new SerialPortOpt();
				// 设置串口的信息设备号、波特率、数据位、停止位、校验位？
				serialPort.mDevNum = preferences.getInt("com", 1);
				serialPort.mSpeed = preferences.getInt("speed", 38400);
				serialPort.mDataBits = preferences.getInt("DataBits", 8);
				serialPort.mStopBits = preferences.getInt("StopBits", 1);
				serialPort.mParity = preferences.getInt("Parity", 'n');
				// 根据设置开启串口
				openSerialPort();
				// //TransToast.show();
				// Intent intent = new Intent(TransmissionActivity.this,
				// ControlPanelActivity.class);
				// startActivity(intent);
				// TransmissionActivity.this.finish();
				// onDestroy();

			}
			if (TransmissionWay.equals("selectWIFI") && mInputStream == null
					|| TransmissionWay.equals("selectSerialport")
					&& serialPort.mFd == null) {

			} else {
				mReadThread = new ReadThread();
				mReadThread.start();
			}
		}
	}

	String getTopActivity(Activity context) {
		ActivityManager manager = (ActivityManager) context
				.getSystemService(ACTIVITY_SERVICE);
		List<RunningTaskInfo> runningTaskInfos = manager.getRunningTasks(1);

		if (runningTaskInfos != null)
			return (runningTaskInfos.get(0).topActivity).toString();
		else
			return null;
	}

	public void initConn() {
		initScreenScale();
		try {
			conn = new ConnThread();
			conn.start();
		} catch (SecurityException e) {
			DisplayError("SecurityException");
		} catch (InvalidParameterException e) {
			DisplayError("InvalidParameterException");
		}
	}

	protected abstract void onDataReceived(final byte[] buffer, final int size,
			final int count);

	@Override
	protected void onDestroy() {
		shutdownConn();
		super.onDestroy();
	}

	public void shutdownConn() {
		if (mReadThread != null) {
			mReadThread.interrupt();
		}
		if (TransmissionWay.equals("selectWIFI")) {
			if (socket != null) {
				if (socket.isConnected()) {
					try {
						mOutputStream.close();
						mInputStream.close();
						socket.close();
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
			}
		} else if (TransmissionWay.equals("selectSerialport")
				&& serialPort != null) {
			closeSerialPort();
		}
	}

	public void IOMistake() {
		TransToast.show();
		Intent intent = new Intent(this, ControlPanelActivity.class);
		startActivity(intent);
		this.finish();
		onDestroy();
	}

	@Override
	public void onBackPressed() {
		Intent intent = new Intent(this, ControlPanelActivity.class);
		startActivity(intent);
		this.finish();
	}

	

	public int maxForce = 100;
	public int settingForce = 100;
	public int position = 100;
	public int settingPosition = 100;

	public byte[] SET_SETTING_FORCE_PREFIX = new byte[] { (byte) 0x01,
			(byte) 0x10, (byte) 0x00, (byte) 0x6D, (byte) 0x00, (byte) 0x01,
			(byte) 0x02, };

	public byte[] CHANGE_WORK_STATE6 = new byte[] { (byte) 0x01, (byte) 0x10,
			(byte) 0x00, (byte) 0x6B, (byte) 0x00, (byte) 0x01, (byte) 0x02,
			(byte) 0x00, (byte) 0x06, (byte) 0x2E, (byte) 0x89 };

	public byte[] CHANGE_WORK_STATE5 = new byte[] { (byte) 0x01, (byte) 0x10,
			(byte) 0x00, (byte) 0x6B, (byte) 0x00, (byte) 0x01, (byte) 0x02,
			(byte) 0x00, (byte) 0x05, (byte) 0x6E, (byte) 0x88 };

	public byte[] CHANGE_WORK_STATE4 = new byte[] { (byte) 0x01, (byte) 0x10,
			(byte) 0x00, (byte) 0x6B, (byte) 0x00, (byte) 0x01, (byte) 0x02,
			(byte) 0x00, (byte) 0x04, (byte) 0xAF, (byte) 0x48 };

	public byte[] CHANGE_WORK_STATE7 = new byte[] { (byte) 0x01, (byte) 0x10,
			(byte) 0x00, (byte) 0x6B, (byte) 0x00, (byte) 0x01, (byte) 0x02,
			(byte) 0x00, (byte) 0x09, (byte) 0x6E, (byte) 0x8D };

	public byte[] CHANGE_WORK_STATE8 = new byte[] { (byte) 0x01, (byte) 0x10,
			(byte) 0x00, (byte) 0x6B, (byte) 0x00, (byte) 0x01, (byte) 0x02,
			(byte) 0x00, (byte) 0x0B, (byte) 0xEF, (byte) 0x4C };

	public byte[] CHANGE_WORK_STATE9 = new byte[] { (byte) 0x01, (byte) 0x10,
			(byte) 0x00, (byte) 0x6B, (byte) 0x00, (byte) 0x01, (byte) 0x02,
			(byte) 0x00, (byte) 0x0C, (byte) 0xAE, (byte) 0x8E };

	public byte[] CHANGE_WORK_STATE10 = new byte[] { (byte) 0x01, (byte) 0x10,
			(byte) 0x00, (byte) 0x6B, (byte) 0x00, (byte) 0x01, (byte) 0x02,
			(byte) 0x00, (byte) 0x0D, (byte) 0x6F, (byte) 0x4E };

	public byte[] CHANGE_WORK_STATE0 = new byte[] { (byte) 0x01, (byte) 0x10,
			(byte) 0x00, (byte) 0x6B, (byte) 0x00, (byte) 0x01, (byte) 0x02,
			(byte) 0x00, (byte) 0x00, (byte) 0xAE, (byte) 0x8B };

	public byte[] GET_BALL_LOCATION = new byte[] { (byte) 0x01, (byte) 0x03,
			(byte) 0x00, (byte) 0x71, (byte) 0x00, (byte) 0x01, (byte) 0xD4,
			(byte) 0x11 };

	public byte[] GET_MAXBALL_LOCATION = new byte[] { (byte) 0x01, (byte) 0x03,
			(byte) 0x00, (byte) 0x70, (byte) 0x00, (byte) 0x01, (byte) 0x85,
			(byte) 0xD1 };

	public byte[] GET_CURRENT_FORCE = new byte[] { (byte) 0x01, (byte) 0x03,
			(byte) 0x00, (byte) 0x71, (byte) 0x00, (byte) 0x01, (byte) 0xD4,
			(byte) 0x11 };

	public byte[] GET_MAX_FORCE = new byte[] { (byte) 0x01, (byte) 0x03,
			(byte) 0x00, (byte) 0x6C, (byte) 0x00, (byte) 0x01, (byte) 0x44,
			(byte) 0x17 };

	public byte[] SEAT_COROTATION = new byte[] { (byte) 0x01, (byte) 0x10,
			(byte) 0x00, (byte) 0x76, (byte) 0x00, (byte) 0x01, (byte) 0x02,
			(byte) 0x00, (byte) 0x01, (byte) 0x6C, (byte) 0xC6 };

	public byte[] SEAT_REVERSAL = new byte[] { (byte) 0x01, (byte) 0x10,
			(byte) 0x00, (byte) 0x76, (byte) 0x00, (byte) 0x01, (byte) 0x02,
			(byte) 0x00, (byte) 0x02, (byte) 0x2C, (byte) 0xC7 };

	public byte[] SEAT_ROTATE_STOP = new byte[] { (byte) 0x01, (byte) 0x10,
			(byte) 0x00, (byte) 0x76, (byte) 0x00, (byte) 0x01, (byte) 0x02,
			(byte) 0x00, (byte) 0x00, (byte) 0xAD, (byte) 0x06 };
}